
#include "iostream"
#include "vector"
#include "unordered_map"
#include "unordered_set"
#include "algorithm"
#include "string"
#include "list"
#include "string.h"

struct Word{
    char c;
    int cishu=1;
    Word(char a){
        c=a;
    }
};
char upper_char(char a){
    if(a>='a'&&a<='z'){
        a-=32;
    }
    return a;
}
bool is_zimu(char a){
    return (a>='a'&&a<='z')||(a>='A'&&a<='Z');
}
class Solution{
public:
    std::vector<Word> vec;
    std::unordered_map<char,int> tag;
    void run(){
        std::string s;
        bool first= true;
        while(std::getline(std::cin,s)){
            vec.clear();
            tag.clear();
            if(!first){
                printf("\n");
            }
            first=false;
            for(auto c:s){
                if(is_zimu(c)){
                    char C= upper_char(c);
                    if(tag.find(C)==tag.end()){
                        vec.emplace_back(C);
                        tag[C]=vec.size()-1;
                    }else{
                        vec[tag[C]].cishu++;
                    }
                }
            }
            for(int i=0;i<vec.size();i++){
                for(int j=0;j<vec.size()-i-1;j++){
                    if(vec[j].cishu<vec[j+1].cishu){
                        std::swap(vec[j],vec[j+1]);
                    }else if(vec[j].cishu==vec[j+1].cishu){
                        if(vec[j].c>vec[j+1].c){
                            std::swap(vec[j],vec[j+1]);
                        }
                    }
                }
            }
            for(auto &v:vec){
                printf("%c %d\n",v.c,v.cishu);
            }
        }
    }
};

int main() {
//    bool cur_num= true;
Solution().run();
    return 0;
}

